home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
p063b9s.zip
/
UNIT
/
MAILPACK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-03-02
|
13KB
|
421 lines
UNIT MailPack;
{╔══════════════════════════════════════════════════════════════════════════╗}
{║ Mail packer/router Last changed: 02.03.97 SA ║}
{║ ║}
{║ (C) Copyright 1989-97 by ║}
{║ Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager ║}
{║ ║}
{║ This source may not be given to anybody, without the written permission ║}
{║ from The Portal Team. ║}
{╚══════════════════════════════════════════════════════════════════════════╝}
{$I POPDEFS.INC}
INTERFACE
USES Use32;
PROCEDURE PerformPacking(CONST Sched:BYTE);
IMPLEMENTATION
USES Dos, OpString, OpDos, OpDate, OpRoot,
Globals, PoPTypes, MailScan, NetFile, MailUtil, LogFile, StrUtil,
FileUtil, Util, OutUtil, Send2Utl, OpusMsg;
PROCEDURE PerformPacking(CONST Sched: Byte);
VAR
Schedule : TSchedule;
SchedFile : TNetFile;
PntSr, DirSr,
sr : SEARCHREC;
io, GlobZone : INTEGER;
p, ZoneOut : PathStr;
Dest, Via : TFidoAddress;
PROCEDURE FindDestNode(FName: PathStr; VAR Dest, Via: TFidoAddress);
VAR
RightSched:LONGINT;
ch:CHAR;
Num,i:BYTE;
Tab:SendToTabType;
pmh:TPktHeader;
f : TNetFile;
FUNCTION AllCmpAdr(CONST a1,a2:TFidoAddress):BOOLEAN;
BEGIN
AllCmpAdr:=((a1.Zone =a2.Zone ) OR (a2.Zone=-1)) AND
((a1.Net =a2.Net ) OR (a2.Net =-1)) AND
((a1.Node =a2.Node ) OR (a2.Node=-1)) AND
((a1.Point=a2.Point) OR (a2.Point=-1));
END;
FUNCTION AllCmpAdrPoint(CONST a1,a2:TFidoAddress):BOOLEAN;
BEGIN
AllCmpAdrPoint:=((a1.Zone =a2.Zone ) OR (a2.Zone=-1)) AND
((a1.Net =a2.Net ) OR (a2.Net =-1)) AND
((a1.Node =a2.Node ) OR (a2.Node=-1)) AND
((a1.Point<>0) AND (a2.Point=0));
END;
BEGIN
f.Open(FName,SizeOf(TPktHeader),FALSE);
f.Read(pmh,NoKeep,Wait);
f.Close;
GetPktHeadInfo(Pmh,Dest,Via);
Dest:=Via;
SchedFile.SEEK(0);
WHILE (NOT SchedFile.EOF) DO
BEGIN
SchedFile.Read(Schedule,nokeep,wait);
IF (Schedule.Action IN [2,3]) AND ((Schedule.Number=0) OR (Schedule.Number=Sched)) THEN
BEGIN
ReadSendTo(Schedule.Adr,Tab,Num);
FOR i:=1 TO Num DO
IF AllCmpAdr(Via,Tab[i]) OR AllCmpAdrPoint(Via,Tab[i]) THEN
BEGIN
CASE Schedule.Action OF
2 : Via:=Tab[1];
3 : Via:=Tab[i];
END;
IF via.zone=-1 THEN Via.Zone:=Dest.Zone;
IF via.Net=-1 THEN Via.Net:=Dest.Net;
IF via.node=-1 THEN Via.Node:=Dest.node;
IF via.Point=-1 THEN Via.Point:=Dest.Point;
EXIT;
END;
END;
END;
END;
PROCEDURE PackIt(CONST FName: PathStr; CONST Dest, Via: TFidoAddress);
VAR
Flag:BOOLEAN;
DestBusyFile,ViaBusyFile:FILE;
ArcName,OldDir,NewPkt:PathStr;
ch : Char;
an : Byte;
FUNCTION CurrentBundle(CONST Adr: TFidoAddress): PathStr;
VAR
NewAdr:TFidoAddress;
s,ss:PathStr;
Ch:CHAR;
sr:SEARCHREC;
PROCEDURE EraseTruncatedBundles(CONST s: PathStr);
VAR
i,j:BYTE;
sr:SearchRec;
ss,sss:PathStr;
BEGIN
FOR j:=0 TO 6 DO
BEGIN
ss:=COPY(s,1,LENGTH(s)-3)+COPY(DayString[DayType(j)],1,2)+'?';
FINDFIRST(ss,Archive,sr);
WHILE DOSERROR=0 DO
BEGIN
IF sr.size=0 THEN
BEGIN
sss:=JustPathName(ss)+'\'+sr.name;
IF DeleteFile(sss) THEN
AddLog('#','Deleting old truncated '+sr.name);
END;
FINDNEXT(sr);
END;
FindClose(sr);
END;
END;
BEGIN
ss:='';
NewAdr.Zone:=Adr.Zone;
NewAdr.Net:=Cfg.Addresses[Cfg.MainAdrNum].Net-Adr.Net;
NewAdr.Node:=Cfg.Addresses[Cfg.MainAdrNum].Node-Adr.Node;
NewAdr.Point:=Adr.Point;
s:=HoldAreaPath(Adr,TRUE);
IF Adr.Point=0 THEN
s:=s+Address(NewAdr.Net,NewAdr.Node)
ELSE
s:=s+Address(0,Adr.point);
IF Cfg.MailScanner.OldExt THEN s:=s+'MO' ELSE
s:=s+'.'+COPY(TodayString('WWW'),1,2);
s:=s+'?';
ch:=' ';
FINDFIRST(s,Archive,sr);
WHILE DOSERROR=0 DO
BEGIN
IF sr.size>0 THEN
BEGIN
ss:=AddBackSlash(JustPathName(s))+sr.name;
Break;
END ELSE
BEGIN
ch:=sr.name[12];
ss:=AddBackSlash(JustPathName(s))+sr.name;
INC(ss[LENGTH(ss)]);
IF ss[LENGTH(ss)]>'9' THEN ss[LENGTH(ss)]:='0';
END;
FINDNEXT(sr);
END;
FindClose(sr);
IF ss='' THEN
BEGIN
ss:=s;
ss[LENGTH(ss)]:='0';
END;
EraseTruncatedBundles(ss);
CurrentBundle:=ss;
END;
BEGIN
AddLog('!','Packing '+JustFileName(FName)+' to '+Address2Str(Via));
FindNodeInfo(NodesRec,Via);
an:=NodesRec.PackerType;
IF an=0 THEN an:=1;
ch:=Schedule.Stat;
IF ch=' ' THEN ch:='H' ELSE
IF ch='N' THEN ch:='F';
IF MarkNodeBusy(DestBusyFile,Dest) THEN
BEGIN
IF NOT CmpAdr(Via,Dest) THEN Flag:=MarkNodeBusy(ViaBusyFile,Via)
ELSE Flag:=TRUE;
IF Flag THEN
BEGIN
NewPkt:=AddBackSlash(JustPathName(FName))+InventPktName;
ArcName:=CurrentBundle(Via);
IF RenameFile(FName,NewPkt) THEN
BEGIN
GetDir(0,OldDir);
ChangeDir(JustPathName(NewPkt));
IF ArcCommand(an,1,ArcName,JustFileName(NewPkt)) THEN
BEGIN
DeleteFile(NewPkt);
SendAFile(ArcName,Via,ch,STTrunc);
END
ELSE
BEGIN
RenameFile(NewPkt,FName);
END;
ChangeDir(OldDir);
END;
IF NOT CmpAdr(Via,Dest) THEN UnMarkNodeBusy(ViaBusyFile);
END;
UnMarkNodeBusy(DestBusyFile);
END;
END;
PROCEDURE BundleNetMail;
VAR
Hold,Dir,Imp:BOOLEAN;
ts,s,ss,newname:STRING;
faf,ch,ch2:CHAR;
Year,Month,Day,dofw,hour,min,sec,sec100,i:WORD;
Len : LongInt;
h:MsgHdrType;
ph:TPktHeader;
p:POINTER;
Adr,Orig:TFidoAddress;
BusyFile,f:FILE;
pmh:TPktMsgHeader;
t:TNodeStat;
FUNCTION IsOurPoint(Adr:TFidoAddress):BOOLEAN;
VAR
i:BYTE;
BEGIN
Adr.Point:=0;
IsOurPoint:=TRUE;
FOR i:=1 TO MaxAddresses DO
IF CmpAdr(Cfg.Addresses[i],Adr) THEN EXIT;
IsOurPoint:=FALSE;
END;
BEGIN
FOR i:=1 TO GetHighestMsg(Cfg.MailScanner.NetMailDir) DO
BEGIN
IF ReadMsg(Cfg.MailScanner.NetMailDir,i,h,Len,p) THEN
BEGIN
IF h.attribute AND MsgSent=0 THEN
BEGIN
FindMsgAdr(h,p,Len,Orig,Adr);
IF NOT IsOurAddress(Adr) THEN
BEGIN
AddLog('#','Packing msg. #'+Long2Str(i)+' from '+Address2Str(Orig)+' to '+Address2Str(Adr));
FindNodeInfo(NodesRec,Adr);
IF Cfg.MailScanner.StripCrash AND (h.attribute AND MsgCrash<>0) AND
NOT (IsOurAddress(Orig)) THEN
BEGIN
ASM
AND h.attribute,NOT MsgCrash
END;
END;
IF h.attribute AND MsgHold<>0 THEN ch:='H' ELSE
IF h.attribute AND MsgCrash<>0 THEN ch:='C' ELSE ch:='O';
IF ch='O' THEN
BEGIN
FindMsgKludges(p,Len,Dir,Imp,Hold);
IF Hold THEN ch:='H' ELSE
IF Dir THEN ch:='D' ELSE
IF Imp THEN ch:='I';
END;
IF ch<>'O' THEN ch2:=ch ELSE ch2:='F';
IF NOT IsOurPoint(Adr) AND (ch='C') THEN Adr.Point:=0;
IF MarkNodeBusy(BusyFile,Adr) THEN
BEGIN
ASSIGN(f,HoldFileName(Adr,TRUE)+ch+'UT'); FileMode:=ShareWrite+ShareDenyW;
RESET(f,1);
IF IORESULT<>0 THEN
BEGIN
REWRITE(f,1);
FillOutPktHeader(Cfg.Addresses[Cfg.MainAdrNum],Adr,ph);
BLOCKWRITE(f,ph,SIZEOF(ph));
END
ELSE
BEGIN
SEEK(f,FileSize(f)-1);
END;
{ Write message here }
FILLCHAR(pmh,SizeOf(Pmh),0);
WITH pmh DO
BEGIN
startmsg:=2;
orignode:=h.orignode;
destnode:=h.destnode;
orignet:=h.orignet;
destnet:=h.destnet;
attr:=h.attribute;
cost:=h.cost;
MOVE(h.datetime,time,20);
END;
BLOCKWRITE(f,pmh,SizeOf(pmh));
s:=AsciiZ2Str(h.ToUser,36)+#0+AsciiZ2Str(h.FromUser,36)+#0+
AsciiZ2Str(h.Subject,72)+#0;
BLOCKWRITE(f,s[1],LENGTH(s));
BLOCKWRITE(f,p^,len-1); { 24-09-95 }
s:=#0#0;
BLOCKWRITE(f,s[1],2);
CLOSE(f);
IF h.Attribute AND MsgFreq<>0 THEN
BEGIN
s:=AsciiZ2Str(h.Subject,72)+' ';
replace(s,' ',' ',0);
WHILE s<>'' DO
BEGIN
ss:=COPY(s,1,POS(' ',s)-1);
DELETE(s,1,LENGTH(ss)+1);
RequestAFile(ss,Adr,'');
END;
END;
IF h.Attribute AND MsgFile<>0 THEN
BEGIN
s:=AsciiZ2Str(h.Subject,72)+' ';
CASE NodesRec.Flavor OF
'N' : faf:='F';
'C',
'D',
'I' : faf:=NodesRec.Flavor;
ELSE faf:='H';
END;
replace(s,' ',' ',0);
WHILE s<>'' DO
BEGIN
ss:=COPY(s,1,POS(' ',s)-1);
DELETE(s,1,LENGTH(ss)+1);
IF NOT IsOurAddress(Orig) THEN { Routed mail }
BEGIN
ts:='';
FOR t:=nsUnknown TO nsPassWord DO
BEGIN
IF ExistFile(Cfg.Inbound[t]+JustFileName(ss)) THEN
BEGIN
ts:=Cfg.Inbound[t]+JustFileName(ss);
Break;
END;
END;
IF ts<>'' THEN
BEGIN
NewName:=Cfg.FwdFile.SecureDir+JustFileName(ss);
CopyFile(ts,NewName,FALSE,TRUE);
SendAFile(NewName,Adr,faf,1+BYTE(Cfg.MailScanner.KillFwdFiles));
END;
END
ELSE
BEGIN
SendAFile(ss,Adr,ch2,stNothing);
END;
END;
END;
IF (h.attribute AND MsgKill<>0) OR
(Cfg.MailScanner.NetMailBoard<>0) OR
(NOT IsOurAddress(Orig)) THEN
DeleteFile(Cfg.MailScanner.NetMailDir+Long2Str(i)+'.MSG')
ELSE
BEGIN
h.attribute:=h.attribute OR MsgSent;
WriteMsg(Cfg.MailScanner.NetMailDir,i,h,Len,p);
END;
UnMarkNodeBusy(BusyFile);
END;
END;
END;
FreeMemCheck(p,Len);
END;
END;
END;
BEGIN
BundleNetMail;
SchedFile.Open(StartPath+PoPScheduleFileName,SizeOf(TSchedule),FALSE);
IF SchedFile.IOResult=0 THEN
BEGIN
FINDFIRST(Cfg.Outbound+'.*',Directory,DirSr); { Parse all zones }
WHILE DOSERROR=0 DO
BEGIN
IF DirSr.Attr AND Directory<>0 THEN
BEGIN
IF DirSr.Name=JustFileName(Cfg.Outbound) THEN GlobZone:=cfg.Addresses[Cfg.MainAdrNum].Zone ELSE
BEGIN
p:=Copy(DirSr.Name,POS('.',DirSr.Name)+1,3);
Val('$'+p, GlobZone, io);
END;
ZoneOut:=HoldAreaNameMunge(GlobZone,False);
FINDFIRST(ZoneOut+'????????.OUT',Archive,Sr);
WHILE DOSERROR=0 DO
BEGIN
p:=ZoneOut+sr.name;
FindDestNode(p,Dest,Via);
PackIt(p,Dest,via);
FINDNEXT(Sr);
END;
FindClose(Sr);
FINDFIRST(ZoneOut+'????????.PNT',Directory,PntSr);
WHILE DOSERROR=0 DO
BEGIN
FINDFIRST(ZoneOut+PntSr.name+'\????????.OUT',Archive,Sr);
IF PntSr.Attr AND Directory<>0 THEN
BEGIN
WHILE DOSERROR=0 DO
BEGIN
p:=ZoneOut+PntSr.name+'\'+sr.name;
FindDestNode(p,Dest,Via);
PackIt(p,Dest,via);
FINDNEXT(Sr);
END;
FindClose(Sr);
END;
FINDNEXT(PntSr);
END;
FindClose(PntSr);
END;
FINDNEXT(DirSr);
END;
FindClose(DirSr);
SchedFile.Close;
END;
END;
END.